package com.sob.lupus.entidades;

import java.awt.Rectangle;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import com.sob.lupus.Arena;
import com.sob.lupus.Arena.Tile;
import com.sob.lupus.Camara;

public class Jugador extends Entidad {
	public static final float XVEL_INC=1f;
	public static final float YVEL_INC=1f;
	
	public static final float XVEL_MAX=4f;
	public static final float YVEL_MAX=-9f;
	
	public static final float GRAVEDAD=0.3f;
	public static final float MAXGRAVEDAD=12f;
	public static final float FRICCION=0.24f;
	
	public boolean direccion = true; //true = derecha, false = izquierda
	
	//public static final long COOLDOWN_AGARRE=500;
	/*
	public static final float GRAVEDAD=0.14f;
	public static final float MAXGRAVEDAD=7f;
	public static final float FRICCION=0.24f;
	public static final long COOLDOWN_AGARRE=500;
	*/
	//public long timerAgarre;
	
	//public boolean puedeAgarrarsee=true;	
	
	public int preX, preY;
	public float xinc, yinc;
	
	public Estado estado=Estado.Aire;
	//public int direccionAgarre=0;
	
	
	public enum Estado{
		Suelo, Aire, Salto,
	}
	
	public Jugador() throws SlickException
	{
		super("/res/chara.png");
	}
	
	public void render(int xOff, int yOff)
	{		
		draw(x+xOff, y+yOff);
	}

	public void tick(Arena arena, Camara camara, int deltaTime, Input input) {
		//enSuelo=false;
		updateInput(input);

		//if(estado!=Estado.Agarrado){
			//direccionAgarre=0;
			//estado=Estado.Aire;
		yinc+=GRAVEDAD;
		y+=Math.round(yinc);
		
		if(xinc>XVEL_MAX){
			xinc=XVEL_MAX;
		}else if(xinc<-XVEL_MAX){
			xinc=-XVEL_MAX;
		}
		if(yinc>MAXGRAVEDAD){
			yinc=MAXGRAVEDAD;
		}
		
		x+=Math.round(xinc);

		if(xinc<0){
			xinc+=FRICCION;
		}else if(xinc>0){
			xinc-=FRICCION;
		}						

		//if(System.currentTimeMillis()-timerAgarre>=COOLDOWN_AGARRE) puedeAgarrarsee=true;

		if(!colisionVertical(arena)){
			estado=Estado.Aire;
		}
		
		if(colisionLateral(arena)){
			//agarre(arena);				
		}
		//}
		

		camara.xOff = getCX() -(camara.width)/2;
		camara.yOff = getCY() -(camara.height)/2;

		preX=x;
		preY=y;
	}
	
	private void updateInput(Input input)
	{
		input.clearControlPressedRecord();
		
		boolean leftKey = input.isKeyDown(Input.KEY_LEFT);
		boolean rightKey = input.isKeyDown(Input.KEY_RIGHT);
		boolean upKey = input.isKeyDown(Input.KEY_UP);
		boolean downKey = input.isKeyDown(Input.KEY_D);
		boolean iKey = input.isKeyDown(Input.KEY_I);
		
		int inc=5;

		//updateMouseTile(input, arena);
		
		switch(estado)
		{
		case Suelo:
			if(leftKey){
				if(direccion){ 
					super.sprite = sprite.getFlippedCopy(true, false);
					direccion = false;
				}
				xinc-=XVEL_INC;
			}
			if(rightKey){
				if(!direccion){
					super.sprite = sprite.getFlippedCopy(true, false);
					direccion = true;
				}
				xinc+=XVEL_INC;
			}
			if(upKey){
				yinc=YVEL_MAX;
				estado=Estado.Salto;
			}
			break;
		case Salto:
		case Aire:
			if(leftKey){
				xinc-=XVEL_INC;
			}
			if(rightKey){
				xinc+=XVEL_INC;
			}
			break;
		/*	
		case Agarrado:
			//if(input.keyPressedOnce(KeyEvent.VK_LEFT)){
			if(input.isKeyDown(Input.KEY_LEFT)){
				estado=Estado.Salto;
				xinc=-XVEL_MAX;
				yinc=+YVEL_MAX;
				timerAgarre=System.currentTimeMillis();
				puedeAgarrarsee=false;
			}
			//if(input.keyPressedOnce(KeyEvent.VK_RIGHT)){
			if(input.isKeyDown(Input.KEY_RIGHT)){
				estado=Estado.Salto;
				xinc=+XVEL_MAX;
				yinc=+YVEL_MAX;
				timerAgarre=System.currentTimeMillis();
				puedeAgarrarsee=false;
			}
			
			if(downKey){
				estado=Estado.Aire;
				yinc=0;
				timerAgarre=System.currentTimeMillis();
				puedeAgarrarsee=false;
			}
			//if(input.keyPressedOnce(KeyEvent.VK_UP)){
			if(input.isKeyDown(Input.KEY_UP)){
				estado=Estado.Salto;
				yinc=+YVEL_MAX;
				timerAgarre=System.currentTimeMillis();
				puedeAgarrarsee=false;
			}
			break;*/
		}
		
	}
	
	/*
	public boolean agarre(Arena arena)
	{
		boolean res=false;
		
		if(Math.round(yinc)>=0 && (estado==Estado.Aire || estado==Estado.Salto)){
			int direccionX=(int)(xinc/Math.abs(xinc));
			if (direccionX!=0 && yinc>0){
					//Si esta en una esquina
				if(arena.parseCoors( (getCX()+(direccionX*(getWidth()/2)) + direccionX),
						y).tileVal!=Arena.EMPTY){
					if(arena.parseCoors(getCX()+(direccionX*(getWidth()/2) + direccionX),
							y-Arena.TILE_SIZE).tileVal==Arena.EMPTY){
						if(arena.parseCoors( getCX()+((getWidth()/4)*direccionX),
								y+getHeight()).tileVal==Arena.EMPTY){
							if(puedeAgarrarsee){
								res=true;
								y=(y/Arena.TILE_SIZE)*Arena.TILE_SIZE;
								estado=Estado.Agarrado;
								direccionAgarre=direccionX;
							}
						}
					}else{
						//xinc=0;
					}
				}
			}
		}
		
		return res;
	}*/
	
	private boolean colisionLateral(Arena arena)
	{
		boolean res=false;
		int direccionX=(int)(xinc/Math.abs(xinc));
		int direccionY=0; //(int)(yinc/Math.abs(yinc));
		
		if (direccionX!=0){
			Rectangle sBounds = getBounds();
			
			for(int base=0;base<getHeight()/Arena.TILE_SIZE;base++){

				int tilex=(int)((getCX()+((getWidth()/2)*direccionX)) / Arena.TILE_SIZE);
				int tiley=(int)(((y+Arena.TILE_SIZE/2)+(base*Arena.TILE_SIZE)) / Arena.TILE_SIZE);

				Tile ts=arena.getTile(tilex, tiley);
				if(ts==null) continue;
				
				if(ts.tileVal!=Arena.EMPTY){
									
					Rectangle tBounds = new Rectangle(tilex*Arena.TILE_SIZE,
													  tiley*Arena.TILE_SIZE,
													  Arena.TILE_SIZE,
													  Arena.TILE_SIZE);
					
					if(sBounds.intersects(tBounds))
					{						
						res=true;
						x=x-direccionX;
						//xinc=0;
						//y=y-direccionY;
						colisionLateral(arena);
						break;
					}
				}
			}
		}
		return res;
	}
	
	private boolean colisionVertical(Arena arena)
	{
		boolean res=false;
		
		int direccionX=0; //(int)(xinc/Math.abs(xinc));
		int direccionY=(int)(yinc/Math.abs(yinc));
		
		if (direccionY!=0){
			Rectangle sBounds = getBounds();
			
			
			for(int base=0;base<getWidth()/Arena.TILE_SIZE;base++){
				
				int tilex=(int)(((x+Arena.TILE_SIZE/2)+(base*Arena.TILE_SIZE)) / Arena.TILE_SIZE);
				int tiley=(int)((getCY()+((getHeight()/2)*direccionY)) / Arena.TILE_SIZE);

				Tile ts=arena.getTile(tilex, tiley);//(x+base*Arena.TILE_SIZE, getCY()+((height/2)*direccionY));
				if(ts==null) continue;
				
				
				if(ts.tileVal!=Arena.EMPTY){
				
					Rectangle tBounds = new Rectangle(tilex*Arena.TILE_SIZE,
													  tiley*Arena.TILE_SIZE,
													  Arena.TILE_SIZE,
													  Arena.TILE_SIZE);
					
					if(sBounds.intersects(tBounds)){
						res=true;
						y-=direccionY;
						colisionVertical(arena);
						yinc=0;
						if(direccionY>=0){
							estado=Estado.Suelo;							
						}
						break;
					}
				}
			}
		}
		return res;
	}
}